library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;

entity vgaGenerator is
  port(clk50_in 		: in std_logic;
		 user_coords  	: in std_logic_vector(19 downto 0); --horizontal: 19 downto 10, --vertical: 9 downto 0
       red_out 	 	: out std_logic_vector(3 downto 0);
       green_out		: out std_logic_vector(3 downto 0);
       blue_out  		: out std_logic_vector(3 downto 0);
       hs_out    		: out std_logic;
       vs_out    		: out std_logic);
end vgaGenerator;

architecture Behavioral of vgaGenerator is

signal clk25              : std_logic;
signal horizontal_counter : std_logic_vector (9 downto 0);
signal vertical_counter   : std_logic_vector (9 downto 0);

begin

-- generate a 25Mhz clock (pixel clock)
process (clk50_in)
begin
  if rising_edge(clk50_in) then
    clk25 <= NOT(clk25);
  end if;
end process;

process (clk25) 
begin
 
   if rising_edge(clk25) then
	
	--checks if setup times has passed
	--horizontal > Back Porch (48px) + Sync Pulse (96px) && < Back Porch (48px) + Sync Pulse (96px) + 640px
	--vertical > && < 480px
    if (horizontal_counter >= "0010010000" ) -- 144
    and (horizontal_counter < "1100010000" ) -- 784
    and (vertical_counter >= "0000100111" ) -- 39
    and (vertical_counter < "1000000111" ) -- 519
    then
  
		--SET TO BLACK
		red_out <= conv_std_logic_vector(0,4);
		green_out <= conv_std_logic_vector(0,4);
		blue_out <= conv_std_logic_vector(0,4);
		
		--CREATE BLUE SKY
		if (horizontal_counter >= "0010010000" ) -- 144
		and (horizontal_counter < "1100010000" ) -- 784
		and (vertical_counter >= "0000100111" ) -- 39
		and (vertical_counter < "0111100000" ) -- 480
		then
			red_out <= conv_std_logic_vector(0,4);
			green_out <= conv_std_logic_vector(0,4);
			blue_out <= conv_std_logic_vector(255,4);
		end if;
		
		--CREATE A YELLOW BALL
		-- user_coords(19 downto 10)  => horizontal center
		-- user_coords(9 downto 0)  => vertical center
		-- 2500  => 100px wide (50 x 50)
		-- delta y: conv_integer(vertical_counter)-conv_integer(user_coords(9 downto 0)
		-- delta x: conv_integer(horizontal_counter)-conv_integer(user_coords(19 downto 10)
		
		if ((abs(conv_integer(vertical_counter)-conv_integer(user_coords(9 downto 0)))*abs(conv_integer(vertical_counter)-conv_integer(user_coords(9 downto 0))) + --delta y * delta y
		abs(conv_integer(horizontal_counter)-conv_integer(user_coords(19 downto 10)))*abs(conv_integer(horizontal_counter)-conv_integer(user_coords(19 downto 10))))  --delta x * delta x
		<= 2500) --radie * radie
		then
			red_out <= conv_std_logic_vector(150,4);
			green_out <= conv_std_logic_vector(255,4);
			blue_out <= conv_std_logic_vector(0,4);
		end if;
		
		--CREATE GREEN GRASS
		if (horizontal_counter >= "0010010000" ) -- 144
		and (horizontal_counter < "1100010000" ) -- 784
		and (vertical_counter >= "0111100000" ) -- 480
		and (vertical_counter < "1000000111" ) -- 519
		then
			red_out <= conv_std_logic_vector(0,4);
			green_out <= conv_std_logic_vector(255,4);
			blue_out <= conv_std_logic_vector(0,4);
		end if;
		
	else
		--during setup, set RGB to 0
		red_out <= conv_std_logic_vector(0,4);
		green_out <= conv_std_logic_vector(0,4);
		blue_out <= conv_std_logic_vector(0,4);
	end if;

	if (horizontal_counter > "0000000000" )
		and (horizontal_counter < "0001100001" ) -- 96+1
	then
		--Horizontal Sync Pulse, new pixel
		hs_out <= '0';
	else
		--Horizontal Sync Pulse = 1 when passing pixelcolors
		hs_out <= '1';
	end if;
	 
	if (vertical_counter > "0000000000" )
		and (vertical_counter < "0000000011" ) -- 2+1
	then
		--Vertical Sync Pulse, new row
		vs_out <= '0';
	else
		--Vertical Sync Pulse = 1 when passing pixelcolors
		vs_out <= '1';
	end if;

	--inclements horizontal_counter to keep track of horizontal position
	horizontal_counter <= horizontal_counter+"0000000001";
	
	if (horizontal_counter="1100100000") then --800 => Back Porch (48px) + Sync Pulse (96px) + 640px + Front Porch(16px)
		--if endline inclement Verical position, reset Horizontal position
		vertical_counter <= vertical_counter+"0000000001";
		horizontal_counter <= "0000000000";
	end if;
	 
	if (vertical_counter="1000001001") then --521
		--if endscreeen reset Verical position
		vertical_counter <= "0000000000";
	end if;
	 
	end if;
end process;

end Behavioral;